package view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import model.GroceryListDao;
import model.JTextFieldLimit;

import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException;

/**
 * A panel to represent the data that's needed to add an item
 * @author Lawrence Grass
 */
@SuppressWarnings("serial")
public class AddItemPanel extends JPanel{
	
	private GroceryListFrame frame;
	
	private JTextField name;
	
	private JTextField qty;
	
	private JTextField cost;
	
	private JTextField department;
	
	private JCheckBox sale;
	
	private GroceryListDao dao;
	
	public AddItemPanel(GroceryListFrame frame, GroceryListDao dao){
		super();
		this.dao = dao;
		this.frame = frame;
		this.setLayout(new BorderLayout());
		JPanel formPanel = new JPanel();
		formPanel.setLayout(new BoxLayout(formPanel, BoxLayout.Y_AXIS));
		
		//name field
		JPanel nameFieldPanel = new JPanel();
		JLabel nameLabel = new JLabel("Item Name: ");
		name = new JTextField(20);
		name.setDocument(new JTextFieldLimit(80));
		nameFieldPanel.add(nameLabel);
		nameFieldPanel.add(name);
		formPanel.add(nameFieldPanel);
		
		//quantity field
		JPanel qtyFieldPanel = new JPanel();
		JLabel qtyLabel = new JLabel("How many: ");
		qty = new JTextField(20);
		qty.setInputVerifier(new IntVerifier());
		qtyFieldPanel.add(qtyLabel);
		qtyFieldPanel.add(qty);
		formPanel.add(qtyFieldPanel);
		
		//cost field
		JPanel costFieldPanel = new JPanel();
		JLabel costLabel = new JLabel("Price per item: ");
		cost = new JTextField(20);
		cost.setInputVerifier(new DoubleVerifier());
		costFieldPanel.add(costLabel);
		costFieldPanel.add(cost);
		formPanel.add(costFieldPanel);
		
		//department field
		JPanel departmentFieldPanel = new JPanel();
		JLabel departmentLabel = new JLabel("Item Department: ");
		department = new JTextField(20);
		department.setDocument(new JTextFieldLimit(80));
		departmentFieldPanel.add(departmentLabel);
		departmentFieldPanel.add(department);
		formPanel.add(departmentFieldPanel);
		
		//sale field
		JPanel saleFieldPanel = new JPanel();
		JLabel saleLabel = new JLabel("On sale?: ");
		sale = new JCheckBox();
		saleFieldPanel.add(saleLabel);
		saleFieldPanel.add(sale);
		formPanel.add(saleFieldPanel);
		
		this.add(formPanel, BorderLayout.NORTH);
		JPanel buffer = new JPanel();
		buffer.setPreferredSize(new Dimension(400, 340));
		this.add(buffer, BorderLayout.CENTER);
		this.add(controlPanel(), BorderLayout.SOUTH);
	}
	
	/**
	 * A helper method to create the options panel on the bottom of the screen
	 */
	private JPanel controlPanel(){
		JPanel controls = new JPanel();
		controls.setBackground(Color.gray);
		controls.setPreferredSize(new Dimension(400, 50));
		JButton back = new JButton("Back");
		back.setPreferredSize(new Dimension(120, 20));
		back.addActionListener(new ItemFormListener(this));
		controls.add(back);
		JButton done = new JButton("Add Item");
		done.setPreferredSize(new Dimension(120, 20));
		done.addActionListener(new ItemFormListener(this));
		controls.add(done);
		return controls;
	}
	
	/**
	 * A helper mehod to clear the fields
	 */
	private void clearFields(){
		name.setText("");
		qty.setText("0");
		cost.setText("0");
		department.setText("");
		sale.setSelected(false);
	}
	
	/**
	 * An input verifier to make sure the quantity and price are an int and not a string
	 * @author Lawrence Grass
	 */
	private class IntVerifier extends InputVerifier {
		@Override
		public boolean verify(JComponent input) {
			JTextField tf = (JTextField) input;
			try {
				Integer.parseInt(tf.getText());
				return true;
			}
			catch(NumberFormatException exception) {
				return false;
			}
		}	
	}
	
	/**
	 * An input verifier to make sure the price is a double and not a string
	 * @author Lawrence Grass
	 */
	private class DoubleVerifier extends InputVerifier {
		@Override
		public boolean verify(JComponent input) {
			JTextField tf = (JTextField) input;
			try {
				Double.parseDouble(tf.getText());
				return true;
			}
			catch(NumberFormatException exception) {
				return false;
			}
		}	
	}
	
	private class ItemFormListener implements ActionListener {
		private AddItemPanel parent;
		private ItemFormListener(AddItemPanel parent){
			this.parent = parent;
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			JButton source = (JButton) e.getSource();
			if(source.getText().equals("Add Item")){
				String item = name.getText();
				try {
					
					//make sure the fields are not empty
					if (item.equals("")) {
						JOptionPane.showMessageDialog(frame,
							    "Items need to have names.");
					} else if (qty.getText().equals("0") || Integer.parseInt(qty.getText()) < 0) {
						JOptionPane.showMessageDialog(frame,
							    "Items need to have a quantity greater than 0.");
					} else if (qty.getText().equals("")) {
						JOptionPane.showMessageDialog(frame,
							    "Items need to have a quantity.");
					} else if (cost.getText().equals("0") || Double.parseDouble(cost.getText()) < 0) {
						JOptionPane.showMessageDialog(frame,
							    "Items generally have a positive non-zero cost, please correct this.");
					} else if (cost.getText().equals("")) {
						JOptionPane.showMessageDialog(frame,
							    "Items need to have a cost.");
					} else if (department.getText().equals("")) {
						JOptionPane.showMessageDialog(frame,
							    "Items need a department to belong to.");
					} else {
						//correct the name to work with MySQL
						if(item.contains("'")){
							item = item.replace("'", "\'");
						}
						//make sure the item isn't already on the list
						if(dao.canAddItem(item))
						{
							System.out.println("add the data");
							dao.addToHistoryTable(item, Integer.parseInt(qty.getText()));
							dao.addToItemLocationTable(item, department.getText());
							dao.addToItemTable(item, Double.parseDouble(cost.getText()), sale.isSelected());
							dao.addToShoppingListTable(item, Integer.parseInt(qty.getText()));
							frame.refreshCards();
							frame.goBack();
						}
						else
						{
							int n = JOptionPane.showConfirmDialog(
								    frame,
								    "Item already exists, replace it?",
								    "Existing item encountered",
								    JOptionPane.YES_NO_OPTION);
							if(n == 0)
							{
								dao.deleteItem(item);
								dao.addToHistoryTable(item, Integer.parseInt(qty.getText()));
								dao.addToItemLocationTable(item, department.getText());
								dao.addToItemTable(item, Double.parseDouble(cost.getText()), sale.isSelected());
								dao.addToShoppingListTable(item, Integer.parseInt(qty.getText()));
								frame.refreshCards();
								frame.goBack();
							}
						}
					}
				} catch (MySQLIntegrityConstraintViolationException ex){
					JOptionPane.showMessageDialog(frame, "Eggs are not supposed to be green.");
				} catch (NumberFormatException e1) {
					//do nothing
				} catch (Exception e1) {
					//keep on trucking
				}
			} else if (source.getText().equals("Back")){
				parent.clearFields();
				frame.refreshCards();
				frame.goBack();
			}
		}
		

		
		
	}
}
